/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.devs.benchmark.dot;

import java.util.List;
import org.devs.benchmark.modeling.ConnectionType;
import org.devs.benchmark.modeling.CoupledType;
import org.devs.benchmark.modeling.InportType;
import org.devs.benchmark.modeling.ModelType;
import org.devs.benchmark.modeling.OutportType;

/**
 *
 * @author Alejandro Moreno
 */
public class DevsToDot {

    public static String DevsModelToDot(ModelType model) {

        return addGraphEnvelope("G", modelToDot(model, 1));

    }

    public static String modelToDot(ModelType model, int index) {

        String dot = "";

        String indent = getIndent(index + 1);
        dot += toDot(model, indent);

        if (model instanceof CoupledType) {

            CoupledType coupled = (CoupledType) model;

            //dot += indent + "rank = same;\n";
            for (int i = 0; i < coupled.getModels().size(); i++) {

                dot += modelToDot(coupled.getModels().get(i), index + 1);



            }

            List<ConnectionType> connections = coupled.getConnections();

            for (int i = 0; i < connections.size(); i++) {

                dot += indent + connections.get(i).getModelFrom() + "_" + connections.get(i).getPortFrom() + ":e -> " + connections.get(i).getModelTo() + "_" + connections.get(i).getPortTo() + ":w [style = bold];\n";
                //dot += indent + connections.get(i).getModelFrom() + "_" + connections.get(i).getPortFrom() + " -> " + connections.get(i).getModelTo() + "_" + connections.get(i).getPortTo() + " [style = bold];\n";


            }



        }

        return addSubGraphEnvelope(model.getName(), dot, index);

    }

    public static String toDot(ModelType model, String indent) {

        String dot = "";
        List<InportType> inports = model.getInports();
        String source = "{rank = source;";
        

        for (int j = 0; j < inports.size(); j++) {

            dot += indent + model.getName() + "_" + inports.get(j).getName() + " [label =\"" + inports.get(j).getName() + "\", style=filled,  shape = box3d];\n";
            source += " " + model.getName() + "_" + inports.get(j).getName() + ";";
        }


        List<OutportType> outports = model.getOutports();
        String sink = "{rank = sink;";
        

        for (int j = 0; j < outports.size(); j++) {

            dot += indent + model.getName() + "_" + outports.get(j).getName() + " [label =\"" + outports.get(j).getName() + "\", style=filled, shape = box3d];\n";
            sink += " " + model.getName() + "_" + outports.get(j).getName() + ";";
        }


        dot += indent + source + "}\n";
        dot += indent + sink + "}\n";

        return dot;
    }

    public static String addGraphEnvelope(String name, String message) {

        return "digraph " + name + " {\n\tconcentrate=true;\n" + message + "\n}\n";

    }

    public static String addSubGraphEnvelope(String name, String message, int index) {

        String indent = getIndent(index);
        String dot = indent + "subgraph cluster" + name + " {\n";
        dot += indent + "\tlabel = \"" + name + "\";\n";
        return dot + message + "\n" + indent + "}\n";

    }

    public static String getIndent(int index) {
        String indent = "";

        for (int i = 0; i < index; i++) {
            indent += "\t";
        }

        return indent;
    }
}
